home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / DJGPP / CBGRX103.ZIP / contrib / libgrx / src / setmode.c < prev    next >
Text File  |  1993-12-06  |  9KB  |  329 lines

  1. /**
  2.  ** SETMODE.C
  3.  **
  4.  **  Copyright (C) 1992, Csaba Biegl
  5.  **    820 Stirrup Dr, Nashville, TN, 37221
  6.  **    csaba@vuse.vanderbilt.edu
  7.  **
  8.  **  This file is distributed under the terms listed in the document
  9.  **  "copying.cb", available from the author at the address above.
  10.  **  A copy of "copying.cb" should accompany this file; if not, a copy
  11.  **  should be available from where this file was obtained.  This file
  12.  **  may not be distributed without a verbatim copy of "copying.cb".
  13.  **  You should also have received a copy of the GNU General Public
  14.  **  License along with this program (it is in the file "copying");
  15.  **  if not, write to the Free Software Foundation, Inc., 675 Mass Ave,
  16.  **  Cambridge, MA 02139, USA.
  17.  **
  18.  **  This program is distributed in the hope that it will be useful,
  19.  **  but WITHOUT ANY WARRANTY; without even the implied warranty of
  20.  **  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  21.  **  GNU General Public License for more details.
  22.  **/
  23.  
  24. #define  _SETMODE_C_
  25.  
  26. #include "grx.h"
  27. #include "libgrx.h"
  28. #include "grdriver.h"
  29. #include "interrup.h"
  30.  
  31. #include <stdio.h>
  32. #include <stdlib.h>
  33. #include <string.h>
  34.  
  35.  
  36. GrContext _GrContext;            /* current graphics context */
  37. GrContext _GrVidPage;            /* the whole screen */
  38.  
  39. int  _GrCurrentMode    = GR_default_text;    /* current video mode */
  40. int  _GrCanBcopyInBlit = FALSE;        /* separate R/W pages in adapter */
  41. int  _GrBigFrameBuffer = FALSE;        /* set if frame buffer > 64K */
  42. int  _GrNumColors      = 256;        /* number of colors */
  43. int  _GrAdapterType    = GR_VGA;    /* type of video adapter */
  44. int  _GrDriverIndex    = 0;        /* low-level video routine selector */
  45. int  _GrRdOnlyOffset   = 0;        /* add for read-only video page */
  46. int  _GrWrOnlyOffset   = 0;        /* add for write-only video page */
  47.  
  48. int  _GrScreenX = 80;            /* screen width  */
  49. int  _GrScreenY = 25;            /* screen height */
  50.  
  51. char _GrMouseDrawn = 0;            /* set if mouse drawn */
  52. char _GrMouseCheck = 0;            /* set if mouse blocking needed */
  53.  
  54. static void dummy(void) {}
  55.  
  56. int  (*_GrMouseBlock)(GrContext *c,int x1,int y1,int x2,int y2);
  57. void (*_GrMouseUnBlock)(int);
  58. void (*_GrMouseUnInit)(void) = dummy;
  59.  
  60. static void (*setmodehook)(void) = NULL;
  61.  
  62. #ifndef _SINGLE_MODE_
  63. handler  _GrResetValues[NumOfHandlers]      = { NULL };
  64. handler *_GrResetAddresses[NumOfHandlers] = { NULL };
  65. #endif
  66.  
  67. struct mode_entry {
  68.     short w,h,c,mode_no;
  69. };
  70.  
  71. static struct mode_entry mode_table[] = {
  72.     { 80,  25,  2,   0x07 },    /* text modes */
  73.     { 40,  25,  16,  0x01 },
  74.     { 80,  25,  16,  0x03 },
  75.     { 320, 200, 16,  0x0d },    /* graphics modes */
  76.     { 640, 200, 16,  0x0e },
  77.     { 640, 350, 16,  0x10 },
  78.     { 640, 480, 16,  0x12 },
  79.     { 800, 600, 16,  (-1) },    /* we have to trust the user's mode number on this */
  80.     { 320, 200, 256, 0x13 }
  81. };
  82.  
  83. static int set_BIOS_mode(int BIOSno,int wdt,int hgt,int col,int *modep)
  84. {
  85.     struct mode_entry *mp = mode_table;
  86.     int count = sizeof(mode_table) / sizeof(mode_table[0]);
  87.     REGISTERS reg;
  88.     int retval;
  89.  
  90.     for( ; --count >= 0; mp++) {
  91.         if(mp->w != wdt) continue;
  92.         if(mp->h != hgt) continue;
  93.         if(mp->c != col) continue;
  94.         if(wdt >= 320) {
  95.         if(mp->mode_no != (-1)) BIOSno = mp->mode_no;
  96.         retval = (col == 16) ? (GRD_VGA | GRD_4_PLANES) : (GRD_VGA | GRD_8_PLANES);
  97.         *modep = GR_width_height_color_graphics;
  98.         }
  99.         else {
  100.         BIOSno = mp->mode_no;
  101.         retval = GRD_VGA | GRD_4_PLANES;
  102.         *modep = GR_width_height_text;
  103.         }
  104.         reg.r_ax = BIOSno;
  105.         int10(®);
  106.         _GrScreenX = wdt;
  107.         _GrScreenY = hgt;
  108.         return(retval);
  109.     }
  110.     return(-1);
  111. }
  112.  
  113. static void int_setmode(int mode,int BIOSno,int width,int height,int colors)
  114. {
  115.     long planesize;
  116.     int  flags;
  117.     int  planes;
  118.  
  119.     (*_GrMouseUnInit)();
  120. #ifndef _SINGLE_MODE_
  121.     for(flags = 0; flags < NumOfHandlers; flags++) {
  122.         if(_GrResetValues[flags] == NULL) continue;
  123.         *(_GrResetAddresses[flags]) = _GrResetValues[flags];
  124.     }
  125. #endif
  126.     if((mode >= GR_80_25_text) && (mode <= GR_width_height_color_graphics)) {
  127.         memset(&_GrVidPage,0,sizeof(GrContext));
  128.         flags = (BIOSno > 0) ?
  129.         set_BIOS_mode(BIOSno,width,height,colors,&mode) :
  130.         (int)_GrLowSetMode(mode,width,height,colors);
  131.         _GrCurrentMode = mode;
  132.         switch(flags & GRD_TYPE_MASK) {
  133.           case GRD_VGA:
  134.         _GrVidPage.gc_baseaddr = (char far *)VGA_FRAME;
  135.         _GrAdapterType = GR_VGA;
  136.         break;
  137.           case GRD_EGA:
  138.         _GrVidPage.gc_baseaddr = (char far *)EGA_FRAME;
  139.         _GrAdapterType  = GR_EGA;
  140.         break;
  141.           case GRD_HERC:
  142.         _GrVidPage.gc_baseaddr = (char far *)HERC_FRAME;
  143.         _GrAdapterType  = GR_HERC;
  144.         break;
  145.           case GRD_8514A:
  146.         _GrAdapterType  = GR_8514A;
  147.         break;
  148.           case GRD_S3:
  149.         _GrAdapterType  = GR_S3;
  150.         break;
  151.           default:
  152.         _GrLowSetMode(GR_default_text,0,0,0);
  153.         fputs("GrSetMode: unknown adapter type in driver\n",stderr);
  154.         exit(1);
  155.         }
  156.         switch(planes = (flags & GRD_PLANE_MASK)) {
  157. #if (GRXPLANES & 16)
  158.           case GRD_16_PLANES:
  159.         if(_GrAdapterType != GR_VGA) goto Default;
  160.         _GrDriverIndex = VGA32K_DRIVER;
  161.         _GrNumColors = 32768;
  162.         break;
  163. #endif
  164. #if (GRXPLANES & 8) || (GRXPLANES & MODE_8514A)
  165.           case GRD_8_PLANES:
  166.           case GRD_8_F_PLANES:
  167.         switch(_GrAdapterType) {
  168.           case GR_VGA:
  169.             _GrDriverIndex = VGA256_DRIVER;
  170.             break;
  171.           case GR_8514A:
  172.             _GrDriverIndex = IBM_8514A_DRIVER;
  173.             break;
  174.           case GR_S3:
  175.             _GrDriverIndex = S3_DRIVER;
  176.             break;
  177.           default:
  178.             goto Default;
  179.         }
  180.         _GrNumColors = 256;
  181.         break;
  182. #endif
  183. #if (GRXPLANES & 4)
  184.           case GRD_4_PLANES:
  185.         if(_GrAdapterType == GR_HERC) goto Default;
  186.         _GrDriverIndex = VGA16_DRIVER;
  187.         _GrNumColors = 16;
  188.         break;
  189. #endif
  190. #if (GRXPLANES & 1)
  191.           case GRD_1_PLANE:
  192.         if(_GrAdapterType != GR_HERC) goto Default;
  193.         _GrDriverIndex = HERC_DRIVER;
  194.         _GrNumColors = 2;
  195.         break;
  196. #endif
  197.           default:
  198.           Default:
  199.         _GrLowSetMode(GR_default_text,0,0,0);
  200.         fputs("GrSetMode: bad color plane # in driver\n",stderr);
  201.         exit(1);
  202.         }
  203.         if(mode >= GR_320_200_graphics) {
  204.         planesize = GrPlaneSize(_GrScreenX,_GrScreenY);
  205. #ifdef _MAXVIDPLANESIZE
  206.         if((_GrAdapterType != GRD_8514A) &&
  207.            (_GrAdapterType != GRD_S3) &&
  208.            (_GrAdapterType != GRD_W9000) &&
  209.            (planesize > _MAXVIDPLANESIZE)) {
  210. #ifdef _MAXBIGVIDPLSIZE
  211.             if(planesize <= _MAXBIGVIDPLSIZE) {
  212.             _GrVidPage.gc_baseaddr = (char far *)BIG_VGA_FRAME;
  213.             _GrBigFrameBuffer = TRUE;
  214.             if((flags & GRD_PAGING_MASK) == GRD_RW_64K) {
  215.                 _GrCanBcopyInBlit = TRUE;
  216.                 _GrRdOnlyOffset   = BIG_RDONLY_OFF;
  217.                 _GrWrOnlyOffset   = BIG_WRONLY_OFF;
  218.             }
  219.             else {
  220.                 _GrCanBcopyInBlit = FALSE;
  221.                 _GrRdOnlyOffset   = 0L;
  222.                 _GrWrOnlyOffset   = 0L;
  223.             }
  224.             }
  225.             else
  226. #endif
  227.             {
  228.             _GrLowSetMode(GR_default_text,0,0,0);
  229.             fputs("GrSetMode: graphics mode too big\n",stderr);
  230.             exit(1);
  231.             }
  232.         }
  233.         else
  234. #endif
  235.         if(planesize < 0x10000L) {
  236.             _GrCanBcopyInBlit = TRUE;
  237.             _GrBigFrameBuffer = FALSE;
  238.             _GrRdOnlyOffset   = 0;
  239.             _GrWrOnlyOffset   = 0;
  240.         }
  241.         else if((flags & GRD_PAGING_MASK) == GRD_RW_64K) {
  242.             _GrCanBcopyInBlit = TRUE;
  243.             _GrBigFrameBuffer = TRUE;
  244.             _GrRdOnlyOffset   = RDONLY_OFF;
  245.             _GrWrOnlyOffset   = WRONLY_OFF;
  246.         }
  247.         else {
  248.             _GrCanBcopyInBlit = FALSE;
  249.             _GrBigFrameBuffer = TRUE;
  250.             _GrRdOnlyOffset   = 0;
  251.             _GrWrOnlyOffset   = 0;
  252.         }
  253.         _GrVidPage.gc_onscreen     = TRUE;
  254.         _GrVidPage.gc_frameaddr  = BASE_ADDRESS(&_GrVidPage);
  255.         _GrVidPage.gc_lineoffset = GrLineOffset(_GrScreenX);
  256.         _GrVidPage.gc_xmax = _GrVidPage.gc_xcliphi = _GrScreenX - 1;
  257.         _GrVidPage.gc_ymax = _GrVidPage.gc_ycliphi = _GrScreenY - 1;
  258.         _GrContext = _GrVidPage;
  259.         switch(_GrNumColors) {
  260.             case 16:  _GrP4Init(flags & GRD_MEM_MASK); break;
  261. #ifndef _INLINE256
  262.             case 256: if(_GrAdapterType == GR_VGA) _GrP8Init(planes); break;
  263. #endif
  264.             default:  break;
  265.         }
  266.         GrRefreshColors();
  267.         _GrMouseDrawn = 0;
  268.         _GrMouseCheck = 0;
  269.         }
  270.         if(setmodehook != NULL) (*setmodehook)();
  271.     }
  272. }
  273.  
  274. void GrSetMode(int mode,int width,int height,int colors)
  275. {
  276.     int_setmode(mode,(-1),width,height,colors);
  277. }
  278.  
  279. void GrSetBIOSMode(int BIOSno,int width,int height,int colors)
  280. {
  281.     int_setmode(GR_80_25_text,((BIOSno > 0) ? BIOSno : 1),width,height,colors);
  282. }
  283.  
  284. void GrSetModeHook(void (*hookfunc)(void))
  285. {
  286.     setmodehook = hookfunc;
  287. }
  288.  
  289. int GrCurrentMode(void)
  290. {
  291.     return(_GrCurrentMode);
  292. }
  293.  
  294. int GrAdapterType(void)
  295. {
  296.     return(_GrAdapterType);
  297. }
  298.  
  299. int GrScreenX(void)
  300. {
  301.     return(_GrScreenX);
  302. }
  303.  
  304. int GrScreenY(void)
  305. {
  306.     return(_GrScreenY);
  307. }
  308.  
  309. int GrSizeX(void)
  310. {
  311.     return(_GrContext.gc_xmax + 1);
  312. }
  313.  
  314. int GrSizeY(void)
  315. {
  316.     return(_GrContext.gc_ymax + 1);
  317. }
  318.  
  319. int GrMaxX(void)
  320. {
  321.     return(_GrContext.gc_xmax);
  322. }
  323.  
  324. int GrMaxY(void)
  325. {
  326.     return(_GrContext.gc_ymax);
  327. }
  328.  
  329.